#ifndef EXPRESSIONFACTORY
#define EXPRESSIONFACTORY

#include <vector>
#include <string>

class PointerList;

class Expression;

/**
	@class ExpressionFactory
	@brief fabrique d'expression

	classe statique permettant à l'analyseur de créer des expressions sans avoir besoin de connaitre la hiérarchisation des classes
*/
class ExpressionFactory
{
	public:
		/**
			@brief creation d'une constante

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression constante entière
			@param [in] value la valeur de la constante
			@return une instance d'expression représentant la constante
		*/
		static Expression* generateConstant ( int value );
		/**
			@brief creation d'une constante

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression constante réelle
			@param [in] value la valeur de la constante
			@return une instance d'expression représentant la constante
		*/
		static Expression* generateConstant ( float value );
		/**
			@brief creation d'une constante

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression constante booléenne
			@param [in] value la valeur de la constante
			@return une instance d'expression représentant la constante
		*/
		static Expression* generateConstant ( bool value );
		/**
			@brief creation d'une constante

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression constante chaine de caractère
			@param [in] value la valeur de la constante
			@return une instance d'expression représentant la constante
		*/
		static Expression* generateConstant ( const char* value );
		/**
			@brief creation d'une variable

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression variable (référence à quelque chose qui a été déclaré).
			@param [in] name le nom de la variable
			@return une instance d'expression représentant la variable
		*/
		static Expression* generateVariable ( const std::string& name );
		/**
			@brief creation d'une addition

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x + y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant l'addition
		*/
		static Expression* generateAdd ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une soustraction

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x - y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant la soustraction
		*/
		static Expression* generateSub ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une multiplication

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x * y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant la multiplication
		*/
		static Expression* generateMul ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une division

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x / y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant la division
		*/
		static Expression* generateDiv ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une inversion de signe

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : - x
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le changement de signe
		*/
		static Expression* generateMinus ( Expression* opDroit );
		/**
			@brief creation d'un et booléen

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x && y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le et booléen
		*/
		static Expression* generateAnd ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'un ou booléen

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x || y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le ou booléen
		*/
		static Expression* generateOr ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'un non booléen

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : ! x
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le non booléen
		*/
		static Expression* generateNot ( Expression* opDroit );
		/**
			@brief creation d'une comparaison

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x == y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le test d'égalité
		*/
		static Expression* generateEq ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une comparaison

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x == y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le test d'inégalité
		*/
		static Expression* generateNeq ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une comparaison

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x < y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le test d'infériorité
		*/
		static Expression* generateLt ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une comparaison

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x <= y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le test d'infériorité ou égalité
		*/
		static Expression* generateLte ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une comparaison

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x > y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le test de supériorité
		*/
		static Expression* generateGt ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'une comparaison

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x >= y
			@param [in] opGauche l'instance représentant l'expression opérande gauche
			@param [in] opDroit l'instance représentant l'expression opérande droit
			@return une instance d'expression représentant le test de supériorité ou égalité
		*/
		static Expression* generateGte ( Expression* opGauche, Expression* opDroit );
		/**
			@brief creation d'un acces à un tableau

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : x [ y ]
			@param [in] arrayDef l'instance représentant l'expression représentant le tableau
			@param [in] index l'instance représentant l'expression représentant l'indice dans le tableau
			@return une instance d'expression représentant l'accès au tableau
		*/
		static Expression* generateArray ( Expression* arrayDef, Expression* index );
		/**
			@brief creation d'un acces à une adresse

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : & x
			@param [in] opDroit l'instance représentant l'expression dont on veut l'adresse
			@return une instance d'expression représentant l'accès à l'adresse
		*/
		static Expression* generateAddress ( Expression* opDroit );
		/**
			@brief creation d'un déréférencement

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une expression de type : * x
			@param [in] opDroit l'instance représentant l'expression adresse que l'on veut déréférencer
			@return une instance d'expression représentant le déréférencement
		*/
		static Expression* generateDeref ( Expression* opDroit );
		/**
			@brief creation d'un appel de fonction

			Cette fonction va créer une instance de la classe ad-hoc pour gérer une instruction de type : f ( expressions )
			@param [in] name le nom de la fonction à appeler
			@param [in] listeExpression l'instance de liste contenant la représentation interne des expressions à passer en argument
			@return une instance d'expression représentant l'appel de fonction
		*/
		static Expression* generateCall ( const std::string& name, std::vector < Expression* > listeExpression );
};

#endif
